#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
事件监听器模块
处理UI事件并协调Service层的服务
"""

import os
from PyQt5.QtCore import QObject, pyqtSlot, Qt
from Service.log_service import LogService
from Service.mining_service import MiningService
from Service.visualization_service import VisualizationService

class EventListener(QObject):
    """事件监听器类，处理UI事件并协调服务"""
    
    def __init__(self, main_window):
        """初始化事件监听器
        
        Args:
            main_window: 主窗口实例
        """
        super().__init__()
        
        # 保存主窗口引用
        self.main_window = main_window
        
        # 初始化服务
        self.log_service = LogService()
        self.mining_service = MiningService()
        self.visualization_service = VisualizationService()
        
        # 连接信号
        self._connect_signals()
    
    def _connect_signals(self):
        """连接UI信号到处理函数"""
        print("开始连接信号")  # 调试信息
        
        # 连接文件菜单动作
        self.main_window.import_action.triggered.connect(self.handle_import_log)
        self.main_window.export_action.triggered.connect(self.handle_export_result)
        
        # 连接控制面板信号
        control_panel = self.main_window.control_panel
        control_panel.algorithm_changed.connect(self.handle_algorithm_changed)
        control_panel.execute_clicked.connect(self.handle_execute_mining)
        
        print("信号连接完成")  # 调试信息
    
    @pyqtSlot(str)
    def handle_algorithm_changed(self, algorithm):
        """处理算法选择改变事件
        
        Args:
            algorithm: 选择的算法名称
        """
        try:
            print(f"算法改变为: {algorithm}")  # 调试信息
            self.main_window.statusBar().showMessage(f'已选择算法: {algorithm}')
        except Exception as e:
            print(f"算法切换错误: {str(e)}")  # 调试信息
            self.main_window.show_error(f"切换算法失败: {str(e)}")
    
    @pyqtSlot()
    def handle_import_log(self):
        """处理日志导入事件"""
        try:
            print("开始导入日志...")  # 调试信息
            
            # 获取文件路径
            file_name, _ = self.main_window.get_open_file_name(
                "选择日志文件",
                "",
                "日志文件 (*.csv *.xes);;所有文件 (*.*)"
            )
            
            print(f"选择的文件: {file_name}")  # 调试信息
            
            if not file_name:
                print("未选择文件")  # 调试信息
                return
            
            # 导入日志文件
            log_info = self.log_service.import_log(file_name)
            
            print(f"日志信息: {log_info}")  # 调试信息
            
            # 更新状态
            self.main_window.statusBar().showMessage(
                f'已导入文件: {os.path.basename(file_name)} '
                f'(案例数: {log_info["case_count"]}, '
                f'事件数: {log_info["event_count"]})'
            )
            
            # 启用控制面板
            self.main_window.control_panel.setEnabled(True)
            
            print("日志导入完成")  # 调试信息
            
        except Exception as e:
            print(f"导入错误: {str(e)}")  # 调试信息
            self.main_window.show_error(f"导入日志失败: {str(e)}")
    
    @pyqtSlot(dict)
    def handle_execute_mining(self, config):
        """处理挖掘执行事件
        
        Args:
            config: 包含算法和参数的配置字典
        """
        try:
            print(f"开始执行挖掘，配置: {config}")  # 调试信息
            
            # 获取事件日志
            event_log = self.log_service.get_event_log()
            if event_log is None:
                raise ValueError("请先导入日志文件")
            
            # 更新进度条
            control_panel = self.main_window.control_panel
            control_panel.set_progress(10)
            
            # 执行挖掘算法
            if config['algorithm'] == 'α算法':
                net, initial_marking, final_marking = self.mining_service.apply_alpha_miner(
                    event_log,
                    config['parameters']
                )
            else:  # Heuristic Miner
                net, initial_marking, final_marking = self.mining_service.apply_heuristics_miner(
                    event_log,
                    config['parameters']
                )
            
            print("挖掘完成，开始可视化")  # 调试信息
            control_panel.set_progress(50)
            
            # 可视化Petri网
            viz_data = self.visualization_service.visualize_petri_net(
                net,
                initial_marking,
                final_marking
            )
            
            # 创建场景
            scene = self.visualization_service.create_scene(viz_data)
            
            # 更新可视化面板
            self.main_window.visualization_panel.scene = scene
            self.main_window.visualization_panel.graphics_view.setScene(scene)
            self.main_window.visualization_panel.graphics_view.fitInView(
                scene.sceneRect(),
                Qt.KeepAspectRatio
            )
            
            # 评估模型
            metrics = self.mining_service.evaluate_model(event_log)
            
            print(f"模型评估结果: {metrics}")  # 调试信息
            
            # 更新状态栏
            self.main_window.statusBar().showMessage(
                f'挖掘完成 - 适合度: {metrics["fitness"]:.2f}, '
                f'精确度: {metrics["precision"]:.2f}, '
                f'简单度: {metrics["simplicity"]:.2f}'
            )
            
            control_panel.set_progress(100)
            print("执行完成")  # 调试信息
            
        except Exception as e:
            print(f"执行错误: {str(e)}")  # 调试信息
            self.main_window.show_error(str(e))
            control_panel.reset_progress()
    
    @pyqtSlot()
    def handle_export_result(self):
        """处理结果导出事件"""
        try:
            print("开始导出结果")  # 调试信息
            
            # 检查是否有结果可导出
            if not self.mining_service.net:
                raise ValueError("没有可导出的结果")
            
            # 获取保存路径
            file_name, format_selected = self.main_window.get_save_file_name(
                "保存结果",
                "",
                "PNG图片 (*.png);;PDF文档 (*.pdf)"
            )
            
            if not file_name:
                print("未选择保存路径")  # 调试信息
                return
            
            print(f"保存到: {file_name}")  # 调试信息
            
            # 确定导出格式
            format = 'png' if '.png' in format_selected.lower() else 'pdf'
            
            # 导出结果
            self.visualization_service.export_petri_net(file_name, format)
            
            # 更新状态栏
            self.main_window.statusBar().showMessage(f'已导出结果到: {file_name}')
            print("导出完成")  # 调试信息
            
        except Exception as e:
            print(f"导出错误: {str(e)}")  # 调试信息
            self.main_window.show_error(f"导出结果失败: {str(e)}")
    
    def cleanup(self):
        """清理资源"""
        try:
            print("开始清理资源")  # 调试信息
            self.visualization_service.cleanup()
            print("清理完成")  # 调试信息
        except Exception as e:
            print(f"清理错误: {str(e)}")  # 调试信息 